package com.lagou.client;

import com.lagou.util.MySerializer;
import org.I0Itec.zkclient.IZkChildListener;
import org.I0Itec.zkclient.ZkClient;

import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

public class BIOClient {

    private static ZkClient zkClient = new ZkClient("101.133.232.19:2181");

    //保持所有连接
    private static Map<String, OutputStream> socketMap = new LinkedHashMap<>();

    //记录请求次数
    private static int count = 1;


    public static void main(String[] args) throws IOException, InterruptedException {
        //使用自定义序列化
        zkClient.setZkSerializer(new MySerializer());
        //获取/server-cluster节点下的所有子节点
        List<String> servers = zkClient.getChildren("/server-cluster");

        if (servers != null && !servers.isEmpty()) {
            //与每台服务器建立连接
            for (String server : servers) {
                String port = zkClient.readData("/server-cluster/" + server).toString();
                Socket socket = new Socket("127.0.0.1", Integer.parseInt(port));
                socketMap.put(port, socket.getOutputStream());
            }
        }

        printConnect(socketMap);


        //注册监听
        zkClient.subscribeChildChanges("/server-cluster", (s, list) -> {
            if (list != null && !list.isEmpty()) {
                Map<String, OutputStream> tempMap = new LinkedHashMap<>();
                for (String server : list) {
                    String port = zkClient.readData("/server-cluster/" + server).toString();
                    //新上线的服务器
                    if (!socketMap.containsKey(port)) {
                        Socket socket = new Socket("127.0.0.1", Integer.parseInt(port));
                        tempMap.put(port, socket.getOutputStream());
                    } else {//剔除已下线服务器
                        tempMap.put(port, socketMap.get(port));
                    }
                    socketMap = tempMap;
                }

                printConnect(socketMap);
            }
        });

        //模拟请求到来
        while (true) {
            //已建立连接的服务器数目
            int size = socketMap.size();
            //简单的hash算法计算请求转发给哪台服务器
            int hash = count % size;

            //向特定server发消息
            int i = 0;
            for (Map.Entry<String, OutputStream> socketEntry : socketMap.entrySet()) {
                if (i == hash) {
                    OutputStream outputStream = socketEntry.getValue();
                    outputStream.write(("Hello Server " + socketEntry.getKey() + "，当前是客户端第" + count + "次请求！").getBytes());
                    outputStream.flush();

                    //打印到控制台方便观察
                    System.out.println("Hello Server " + socketEntry.getKey() + "，当前是客户端第" + count + "次请求！");
                }
                i++;
            }

            //请求序号加1
            count++;
            //每秒一次请求
            Thread.sleep(1000);
        }
    }

    //打印当前连接
    private static void printConnect(Map<String, OutputStream> socketMap) {
        System.out.println("当前已建立连接如下：");
        for (Map.Entry<String, OutputStream> socketEntry : socketMap.entrySet()) {
            System.out.println(socketEntry.getKey());
        }
    }

}
